package util

import (
	"bytes"
	"gitee.com/laofa1/play/k_conf_mng/kconf_backend/pkg/setting"
	"golang.org/x/crypto/ssh"
	knownhosts "golang.org/x/crypto/ssh/knownhosts"
	"io/ioutil"
	"log"
)

func NewSshClient(host, port, user, privateKeyFile string) (*ssh.Client, error) {
	hostKeyCallback, err := knownhosts.New(setting.DockerKnownHosts)
	if err != nil {
		log.Println(err)
		return nil, err
	}

	authMethod, err := PublicKeyMethod(privateKeyFile)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	config := &ssh.ClientConfig{
		User: user,
		Auth: []ssh.AuthMethod{
			authMethod,
		},
		HostKeyCallback: hostKeyCallback,
	}

	conn, err := ssh.Dial("tcp", host + ":" + port, config)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return conn, nil
}

func PublicKeyMethod(file string) (ssh.AuthMethod, error) {
	buffer, err := ioutil.ReadFile(file)
	if err != nil {
		log.Println(err)
		return nil, err
	}

	key, err := ssh.ParsePrivateKey(buffer)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return ssh.PublicKeys(key), nil
}

func RunSshCommand(conn *ssh.Client, command string) (string, error) {
	session, err := conn.NewSession()
	if err != nil {
		log.Println(err)
		return "", err
	}
	defer session.Close()

	var stdOutBuf bytes.Buffer
	var stdErrBuf bytes.Buffer
	session.Stdout = &stdOutBuf
	session.Stderr = &stdErrBuf
	err = session.Run(command)
	msg := stdOutBuf.String() + "\n" + stdErrBuf.String()
	if err != nil {
		log.Println(err, msg)
		return msg, err
	}
	return msg, nil
}